package com.eden.api.security.interceptor;

import com.eden.api.security.LoginUser;
import com.eden.api.security.annotation.AnonymousAccess;
import com.eden.api.security.service.ITokenService;
import com.eden.common.constant.HttpStatus;
import com.eden.common.exception.api.auth.UnauthenticatedException;
import com.eden.common.utils.StringUtils;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.SignatureException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * @description: token过滤器 验证token有效性
 * @author:jiaoyang
 */

@Slf4j
@Component
public class AuthenticationInterceptor extends BaseAuthInterceptor {
    @Autowired
    private ITokenService tokenService;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Class clazz = handlerMethod.getBeanType();
        AnonymousAccess annotation;
        if(clazz.isAnnotationPresent(AnonymousAccess.class)) {
            annotation = (AnonymousAccess) clazz.getAnnotation(AnonymousAccess.class);
            if(log.isDebugEnabled()){
                String clazzName = clazz.getSimpleName();
                String annotationName = annotation.annotationType().getSimpleName();
                log.debug("在类{}上找到注解{}", clazzName, annotationName);
            }
            return true;
        }
        Method method = handlerMethod.getMethod();
        if (method.isAnnotationPresent(AnonymousAccess.class)) {
            annotation = method.getAnnotation(AnonymousAccess.class);
            if(log.isDebugEnabled()){
                String clazzName = ((HandlerMethod) handler).getBeanType().getName();
                String methodName = ((HandlerMethod) handler).getMethod().getName();
                String annotationName = annotation.annotationType().getName();
                log.debug("在类{}的{}方法上找到注解{}", clazzName, methodName, annotationName);
            }
            return true;
        }
        try {
            LoginUser loginUser = tokenService.getLoginUser(request);
            if (StringUtils.isNotNull(loginUser)) {
                tokenService.verifyToken(loginUser);
                return true;
            } else {
                reject(request, response);
                return false;
            }
        } catch (SignatureException | MalformedJwtException e) {
            reject(request, response);
            return false;
        }
    }

    private void reject(HttpServletRequest request, HttpServletResponse response) {
        String requestURI = request.getRequestURI();
        String msg = "身份认证无效，请先登录后操作";
        if (StringUtils.startsWith(requestURI, "/api/")) {
            msg = StringUtils.format("请求访问：{}，认证失败，无法访问系统资源", requestURI);
        }
        //ServletUtils.renderString(response, JSON.toJSONString(ApiResult.error(HttpStatus.UNAUTHORIZED, msg)));
        throw new UnauthenticatedException(HttpStatus.UNAUTHORIZED, msg);
    }
}
